#pragma once
// #autor:yxj
#include "rclcpp/rclcpp.hpp"
#include <agv_peripheral_controller/toolKit.h>
#include <agv_msgs/msg/read_in_puts.hpp>
#include <agv_msgs/msg/read_in_puts_new.hpp>
#include <agv_srvs/srv/outputs_new.hpp>
#include <future>
#include <forward_list>

//仿真外设
//#define  PERIPH_DEBUG 
///////////////////单阻挡举升机构//////////////////////////
namespace peripheral_roller
{
    // 定义输入IO点类型
    using INPUT_IO_TYPE = CDataTimeStamp<agv_msgs::msg::PairTypeInt>;

    // 定义输出控制IO点类型
    // 参数： first:io名字 second:控制输出的电平
    using OUTPUT_IO_TYPE = agv_msgs::msg::PairTypeInt;

    // IO控制输出组
    using IO_GROUP = std::vector<OUTPUT_IO_TYPE>;

    // 手动旋钮的三种状态
    enum class SwitchState
    {
        // 举升
        UP,
        DOWN,
        STOP,
        // 辊筒
        FORWARD,
        REVERSE
    };

    // 检测输入IO信号是否触发
    // 返回：是否触发
    inline bool inputIo(INPUT_IO_TYPE &inputIo)
    {

        bool ret = false;
        // 如果数据有效，判断是否触发
        bool timeOut = inputIo.TimeOut(300);
        bool pressed = inputIo.Get().value;

        if (timeOut)
        {
            DEBUG_ERROR_OUT("inputIo:data time out:key=" << inputIo.Get().key);
            return ret;
        }

        ret = pressed;

        return ret;
    }

    // #1 设置IO输出工具类
    class COutputIoTool
    {
    public:
        COutputIoTool();

        // 控制IO点输出 数组：param1:索引  param2:触发
        // 返回：成功与否
        bool set(IO_GROUP outIoGroup);

        // 初始化客户端
        void init(ros::ServiceClient &client);

    private:
        // 最后输出io的电平状态
        IO_GROUP m_outIoRecord;

        // 控制IO输出客户端
        ros::ServiceClient m_client;
    };

    // #3 单举升类
    class CIoLift
    {
    public:
        // 默认构造
        CIoLift();

        // 默认析构
        ~CIoLift();

        // 初始化
        bool init(ros::ServiceClient &client);

        // 举升上升
        bool up();

        // 举升下降
        bool down();

        // 举升停止
        bool stop();

        // 货物装填---某些举升设备不使用上下限位触发作为是否有无货物
        bool loadStatus();

        // 前上限位
        INPUT_IO_TYPE upLimit;

        // 前下限位
        INPUT_IO_TYPE downLimit;

        // 控制IO点-支持单点控制(上升下降一个点)-支持双点控制(上升10 下降01 停止00)
        IO_GROUP ctrl;

        //
        // 此处特殊处理IO型电机--是否发生了故障以及处理故障
        // 清除一次错误
        bool clearErrorOnce();

        // 是否触发了错误
        bool hasError();

        // IO电机举升控制，增加电机输入检测信号和故障清除
        //  O电机故障检测
        INPUT_IO_TYPE errorIn;

        // IO电机故障清除
        IO_GROUP clearFaultOut;

        // 复位沿变化控制
        std::atomic<bool> resetFlag;
        
       // 上升到位
        bool upTarget();

        // 下降到位
        bool downTarget();

    private:
 
        // 控制io输出工具类
        COutputIoTool m_outputIoTool;

        // 异步清除返回值
        std::forward_list<std::future<void>> m_futures;
    };

}